'use strict';
const http = require('http');
const { Gateway, Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client');
const path = require('path');
const { buildCAClient, registerAndEnrollUser } = require('../../test-application/javascript/CAUtil.js');
const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');

const mspOrg1 = 'Org1MSP';
const mspOrg2 = 'Org2MSP';

const myChannel = 'mychannel';
const myChaincodeName = 'myContractTest3';


//请求交易 ：若用户存在，执行交易
async function trade(UserID,meter){
    var reqNum = 0;
    var bidNum = 0;
    try {
        // 加载网络配置文件和身份凭证
        const ccpPath = buildCCPOrg1();
        const walletPath = path.join(__dirname, 'wallet/org1');
        const wallet = await buildWallet(Wallets, walletPath);
        // 创建一个网关连接
        const gateway = new Gateway();
        await gateway.connect(ccpPath, {
            wallet,
            identity: 'admin',
            discovery: { enabled: true, asLocalhost: true }
        });
        // 获取通道和链码
        const network = await gateway.getNetwork(myChannel);
        const contract = network.getContract(myChaincodeName);

        // 准备参数
        const meter1 = {
            UserId: 'user3',
            Inputs: 3.43,
            Outputs: 2.43,
            Amount: 1.0,
            Price: 0.6
        };
        const meter2 = {
            UserId: 'user4',
            Inputs: 3.43,
            Outputs: 4.43,
            Amount: 1.0,
            Price: 0.7
        };
        const meter3 = {
            UserId: 'user5',
            Inputs: 4.43,
            Outputs: 2.43,
            Amount: 1.0,
            Price: 0.9
        };
        let meters = [meter,meter1,meter2,meter3]
        //从TESP获取一批电表
        let arr = await getMeter()
        for (let m of arr){
            meters.push(m)
        }
        let reqNum = 0;
        let length = meters.length;
        let newLength = 1;
        reqNum+= length - 3;
        while(length!=newLength & newLength!=0){
            length = newLength;
            let randomNum = Math.floor(1000 + Math.random() * 9000);
            const currentDateTime = new Date().toLocaleString();//当前时间

            // 调用合约中的 MatchTrade 函数
            let objJson  = await contract.submitTransaction('MatchTrade', JSON.stringify(meters), randomNum.toString());
            if(objJson.length==0){ break;}
            let resultObject = JSON.parse(objJson);  
            console.log('buyer:'+resultObject.Buyers+'  seller:' + resultObject.Sellers)
            let objJson1  = await contract.submitTransaction('CreateAuction', JSON.stringify(resultObject.Buyers), JSON.stringify(resultObject.Sellers),resultObject.AuctionID,currentDateTime);
            console.log('createAuction:'+objJson1)
            meters = resultObject.NewMeters
            newLength = meters.length;
            bidNum++
        }

        console.log("成功执行 MatchTrade..")
        // 断开与网关的连接
        gateway.disconnect();
        return [reqNum,bidNum];
    } catch (error) {
        console.error(`发生错误: ${error}`);
        process.exit(1);
    }
}

// null
async function addTradeInfo(UserID){
    try {
        // 加载网络配置文件和身份凭证
        const ccpPath = buildCCPOrg1();
        const walletPath = path.join(__dirname, 'wallet/org1');
        const wallet = await buildWallet(Wallets, walletPath);
        // 创建一个网关连接
        const gateway = new Gateway();
        await gateway.connect(ccpPath, {
            wallet,
            identity: 'admin',
            discovery: { enabled: true, asLocalhost: true }
        });
        // 获取通道和链码
        const network = await gateway.getNetwork(myChannel);
        const contract = network.getContract(myChaincodeName);

        // 准备参数

        let auctionId = "auction1"
        // 调用合约中的 GetUserInfo 函数
        const result = await contract.submitTransaction('AddTradeInfo',auctionId,UserID,"1","2","1.8","20","15");

        console.log("成功执行 addTradeInfo.."+result)
        // 断开与网关的连接
        gateway.disconnect();
    } catch (error) {
        console.error(`发生错误: ${error}`);
        process.exit(1);
    }
}

async function createAuction(UserID){
    try {
        // 加载网络配置文件和身份凭证
        const ccpPath = buildCCPOrg1();
        const walletPath = path.join(__dirname, 'wallet/org1');
        const wallet = await buildWallet(Wallets, walletPath);
        // 创建一个网关连接
        const gateway = new Gateway();
        await gateway.connect(ccpPath, {
            wallet,
            identity: 'admin',
            discovery: { enabled: true, asLocalhost: true }
        });
        // 获取通道和链码
        const network = await gateway.getNetwork(myChannel);
        const contract = network.getContract(myChaincodeName);

        // 准备参数

        let auctionId = "auction1"
        // 调用合约中的 GetUserInfo 函数
        const result = await contract.submitTransaction('AddTradeInfo',auctionId,UserID,"1","2","1.8","20","15");

        console.log("成功执行 addTradeInfo.."+result)
        // 断开与网关的连接
        gateway.disconnect();
    } catch (error) {
        console.error(`发生错误: ${error}`);
        process.exit(1);
    }
}

//查询用户信息 (实际不只用来查用户，包括订单等) 
async function getUserInfo(UserID){
    try {
        const ccp = buildCCPOrg1();
        const walletPath = path.join(__dirname, 'wallet/org1');
        const wallet = await buildWallet(Wallets, walletPath);

        const gateway = new Gateway();

		// Connect using Discovery enabled
		await gateway.connect(ccp,
			{ wallet: wallet, identity: 'admin', discovery: { enabled: true, asLocalhost: true } });

		const network = await gateway.getNetwork(myChannel);
		const contract = network.getContract(myChaincodeName);

		console.log('\n--> Evaluate Transaction: query the auction');
		var result = await contract.evaluateTransaction('QueryInfo',UserID);
		console.log('*** Result: getUserInfo: ' + prettyJSONString(result.toString()));

		gateway.disconnect();
    } catch (error) {
        console.error(`发生错误: ${error}`);
        process.exit(1);
    }
    return prettyJSONString(result.toString());
}

async function RegistUser(UserID){
    try {
        // 加载网络配置文件和身份凭证
        const ccpPath = buildCCPOrg1();
        const walletPath = path.join(__dirname, 'wallet/org1');
        const wallet = await buildWallet(Wallets, walletPath);
        // 创建一个网关连接
        const gateway = new Gateway();
        await gateway.connect(ccpPath, {
            wallet,
            identity: 'admin',
            discovery: { enabled: true, asLocalhost: true }
        });
        // 获取通道和链码
        const network = await gateway.getNetwork(myChannel);
        const contract = network.getContract(myChaincodeName);

        // 调用合约中的 GetUserInfo 函数
        const result = await contract.submitTransaction('RegisterUser',UserID,"300","200","0","150");

        console.log("成功执行 RegistUser.."+result)
        // 断开与网关的连接
        gateway.disconnect();
    } catch (error) {
        console.error(`发生错误: ${error}`);
        process.exit(1);
    }

}


//从TESP获取一轮交易电表 return JSONString
function getMeter() {
    return new Promise((resolve, reject) => {
      const options = {
        hostname: '192.168.31.11',
        port: 5000,
        path: '/bidding/false',
        method: 'GET',
      };
  
      const req = http.request(options, (res) => {
        let data = '';
  
        res.on('data', (chunk) => {
          data += chunk;
        });
  
        res.on('end', () => {
          const meters = JSON.parse(data);
          const meterArr = [];
  
          for (const m of meters) {
            if (m[2] !== '0' && m[3] !== '0') {
              let meter = {};
              if (m[1] === 'buyer') {
                meter = {
                  UserId: m[0],
                  Inputs: 0,
                  Outputs: parseFloat(m[3]),
                  Amount: parseFloat(m[3]),
                  Price: parseFloat(parseFloat(m[2]).toFixed(3)),
                };
              } else {
                meter = {
                  UserId: m[0],
                  Inputs: parseFloat(m[3]),
                  Outputs: 0,
                  Amount: parseFloat(m[3]),
                  Price: parseFloat(parseFloat(m[2]).toFixed(3)),
                };
              }
              meterArr.push(meter);
            }
          }
  
          resolve(meterArr);
        });
      });
  
      req.on('error', (error) => {
        reject(error);
      });
  
      req.end();
    });  
}

async function main() {

	if (process.argv[2] === undefined && process.argv[3] === undefined && process.argv[4] === undefined) {
		console.log('Usage: node all.js method org userID');
		process.exit(1);
	}

    
	const method = process.argv[2];
	const org = process.argv[3];
	const userId = process.argv[4];

	try {
		if (org === 'Org1' || org === 'org1') {
            if(method === "QueryInfo"){
                console.log("执行 method: getUserInfo..")
                await getUserInfo(userId);
            }else if(method === "trade"){
                console.log("执行 method: trade..")
                await trade(userId);
            }else if(method === "addTradeInfo"){
                    console.log("执行 method: addTradeInfo..")
                    await addTradeInfo(userId);
            }else if(method === "getMeter"){
                console.log("执行 method: getMeter..")
                await test1();
        }   else{
                console.log("pass,method 不存在..")
            }
		}
		else {
			console.log('Usage: node all.js method org userID');
			console.log('Org must be Org1');
		}
	} catch (error) {
		console.error(`Error : ${error}`);
		process.exit(1);
	}
}

module.exports = {
    getUserInfo,
    trade,
    RegistUser
};
main();
